package igor.lakienko.ru.generation.quotes.service;

import igor.lakienko.ru.generation.quotes.dto.MessageEventDto;
import igor.lakienko.ru.generation.quotes.dto.StockDto;
import igor.lakienko.ru.generation.quotes.entity.StockEntity;
import igor.lakienko.ru.generation.quotes.enums.Stock;
import igor.lakienko.ru.generation.quotes.enums.TypeSecurities;
import igor.lakienko.ru.generation.quotes.mapper.StockMapper;
import lombok.SneakyThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.BDDMockito.given;

@ExtendWith(MockitoExtension.class)
class StockServiceTest {

    @Mock
    StockMapper stockMapper;

    @InjectMocks
    StockService stockService;

    @BeforeEach
    void setUp() {
        getSizeBatchField();
    }

    @Test
    void whenGetStock_thenSuccessRandomStockDto() {
        //given
        StockDto stockDefault = getStockDefault();
        given(stockMapper.stockEntityToDto(any(StockEntity.class))).willReturn(stockDefault);

        //when
        MessageEventDto stock = stockService.getStock();

        //then
        assertThat(stock).isEqualTo(stockDefault);
    }

    @Test
    void whenGetStocks_thenSuccessRandomStockDtos() {
        //given
        List<StockDto> stockDefault = List.of(getStockDefault());
        given(stockMapper.stocksEntityToDto(anyList())).willReturn(stockDefault);

        //when
        Collection<StockDto> stock = stockService.getStocks();

        //then
        assertThat(stock).isEqualTo(stockDefault);
    }

    @SneakyThrows
    private void getSizeBatchField() {
        Field quoteSizeBatch = stockService.getClass().getDeclaredField("quoteSizeBatch");
        quoteSizeBatch.setAccessible(true);
        quoteSizeBatch.set(stockService, 2);
    }

    private StockDto getStockDefault() {
        return StockDto.builder()
                .id(UUID.randomUUID().toString())
                .sentAt(ZonedDateTime.now())
                .type(TypeSecurities.STOCK)
                .stock(Stock.AAPL)
                .bid(BigDecimal.ONE)
                .offer(BigDecimal.TEN)
                .fullStockName(Stock.AAPL.getDescriptionStock())
                .price(100_000.00F)
                .stockVolume(BigInteger.TWO)
                .ebitda(100.00F)
                .dividends(100.00F)
                .profitCompany(BigInteger.TWO)
                .marketCapital(BigDecimal.ONE)
                .build();
    }

}
